// 12_generics.rs
// 演示 Rust 中的泛型（generics）

// 1. 泛型函数
// 泛型函数可以处理不同类型的参数
fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
    let mut largest = list[0];
    
    for &item in list {
        if item > largest {
            largest = item;
        }
    }
    
    largest
}

// 2. 泛型结构体
struct Point<T> {
    x: T,
    y: T,
}

// 为泛型结构体实现方法
impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
    
    fn y(&self) -> &T {
        &self.y
    }
    
    // 方法中可以使用不同的泛型参数
    fn mixup<U>(self, other: Point<U>) -> Point<(T, U)> {
        Point {
            x: (self.x, other.x),
            y: (self.y, other.y),
        }
    }
}

// 为特定类型的泛型结构体实现方法
impl Point<f32> {
    fn distance_from_origin(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}

// 3. 多参数泛型结构体
struct Pair<T, U> {
    first: T,
    second: U,
}

// 为多参数泛型结构体实现方法
impl<T, U> Pair<T, U> {
    fn new(first: T, second: U) -> Self {
        Self {
            first,
            second,
        }
    }
    
    fn swap(self) -> Pair<U, T> {
        Pair {
            first: self.second,
            second: self.first,
        }
    }
}

// 4. 泛型枚举
// Option<T> 就是一个泛型枚举，定义大致如下：
// enum Option<T> {
//     Some(T),
//     None,
// }

// Result<T, E> 也是一个泛型枚举，定义大致如下：
// enum Result<T, E> {
//     Ok(T),
//     Err(E),
// }

// 5. 自定义泛型枚举
#[derive(Debug)]
enum Message<T, U> {
    Quit,
    Move(T, T),
    Write(String),
    ChangeColor(U, U, U),
}

// 6. 泛型约束
// 可以为泛型参数添加约束，限制它们必须实现某些特性
fn print_it<T: std::fmt::Display>(item: T) {
    println!("打印: {}", item);
}

// 使用 + 语法添加多个约束
fn print_and_debug<T: std::fmt::Display + std::fmt::Debug>(item: T) {
    println!("Display: {}", item);
    println!("Debug: {:?}", item);
}

// 使用 where 子句简化多个泛型约束
fn compare_and_print<T, U>(t: T, u: U) 
where 
    T: std::fmt::Display + PartialOrd,
    U: std::fmt::Display + PartialOrd,
{
    if t > u {
        println!("{} > {}", t, u);
    } else if t < u {
        println!("{} < {}", t, u);
    } else {
        println!("{} = {}", t, u);
    }
}

// 7. 泛型返回类型
fn returns_something<T: Default>(t: &T) -> T {
    T::default()
}

// 8. 泛型与所有权
fn take_and_clone<T: Clone>(t: T) -> T {
    t.clone()
}

// 9. 泛型与生命周期（将在生命周期章节详细介绍）
// fn longest<'a, T>(x: &'a T, y: &'a T) -> &'a T 
// where 
//     T: PartialOrd,
// {
//     if x > y {
//         x
//     } else {
//         y
//     }
// }

// 10. 泛型在集合中的应用
fn print_collection<T: std::fmt::Debug>(collection: &[T]) {
    println!("集合内容: {:?}", collection);
}

// 将原来的 main 函数改为公共的 run 函数
pub fn run() {
    // 11. 使用泛型函数
    let number_list = vec![34, 50, 25, 100, 65];
    let result = largest(&number_list);
    println!("最大的数字: {}", result);
    
    let char_list = vec!['y', 'm', 'a', 'q'];
    let result = largest(&char_list);
    println!("最大的字符: {}", result);
    
    // 12. 使用泛型结构体
    let integer_point = Point { x: 5, y: 10 };
    let float_point = Point { x: 1.0, y: 4.0 };
    
    println!("整数点 x 坐标: {}", integer_point.x());
    println!("浮点点 y 坐标: {}", float_point.y());
    
    // 使用特定类型的方法
    let distance = float_point.distance_from_origin();
    println!("浮点点到原点的距离: {}", distance);
    
    // 13. 使用泛型结构体的 mixup 方法
    let p1 = Point { x: 5, y: 10.4 };
    let p2 = Point { x: "Hello", y: 'c' };
    
    let p3 = p1.mixup(p2);
    println!("混合后的点 x: {:?}, y: {:?}", p3.x, p3.y);
    
    // 14. 使用多参数泛型结构体
    let pair = Pair::new(1, "hello");
    println!("原始对: first={}, second={}", pair.first, pair.second);
    
    let swapped = pair.swap();
    println!("交换后的对: first={}, second={}", swapped.first, swapped.second);
    
    // 15. 使用泛型枚举
    let msg1 = Message::Move(10, 20);
    let msg2 = Message::ChangeColor(255, 0, 0);
    
    println!("消息1: {:?}", msg1);
    println!("消息2: {:?}", msg2);
    
    // 16. 使用带有约束的泛型函数
    print_it(5);
    print_it(3.14);
    print_it("Hello");
    
    // print_it(true); // 这会导致编译错误，因为 bool 没有实现 Display trait
    
    print_and_debug(42);
    // print_and_debug(vec![1, 2, 3]); // 这会导致编译错误，因为 Vec 没有实现 Display trait
    
    // 17. 使用 where 子句
    compare_and_print(1, 2);
    compare_and_print(3.14, 2.71);
    compare_and_print("apple", "banana");
    
    // 18. 使用泛型返回类型
    let default_i32 = returns_something(&42);
    let default_string = returns_something(&String::from("hello"));
    
    println!("默认 i32 值: {}", default_i32);
    println!("默认 String 值: {}", default_string);
    
    // 19. 泛型与所有权
    let original = String::from("original");
    let cloned = take_and_clone(original);
    println!("克隆后的字符串: {}", cloned);
    // 注意：original 仍然有效，因为 take_and_clone 接受的是 T 而不是 &T
    // 但实际上，original 被移动到函数中，然后通过克隆返回了一个新的值
    // println!("原始字符串: {}", original); // 这会导致编译错误
    
    // 20. 泛型在集合中的应用
    let numbers = vec![1, 2, 3, 4, 5];
    let strings = vec!["apple", "banana", "cherry"];
    
    print_collection(&numbers);
    print_collection(&strings);
    
    // 21. 泛型的性能
    // Rust 的泛型在编译时会被单态化（monomorphization）
    // 这意味着编译器会为每个使用的具体类型生成专门的代码
    // 因此，使用泛型不会带来运行时性能损失
    
    println!("\n泛型示例演示完成！");
    println!("Rust 的泛型在编译时会被单态化，不会带来运行时性能损失");
    println!("使用泛型可以编写更加通用和可重用的代码");
}